package Day25;


import java.io.*;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;

/**
 * 视图层：专门跟用户打交道（展示给用看的和需要用户输入的都在这里操作）：输入、输出、调用dao中的方法操作数据
 * @Author wanglina
 * @Version 1.0
 */
public class ExpressView {
    private Scanner input=new Scanner(System.in);
    //private ExpressDao expressDao=new ExpressDao();
    private final int PROT = 10086;
    private Socket client;//客户端

    /**
     * 客户端启动
     */
    public void start(){
        OutputStream out = null;
        ObjectOutputStream objOut = null;
        InputStream in = null;
        ObjectInputStream objIn = null;
        try {
            do {
                if (client == null || client.isClosed()) {
                    client = new Socket("127.0.0.1", PROT);
                    in = client.getInputStream();
                    out = client.getOutputStream();
                    objOut = new ObjectOutputStream(out);
                    objIn = new ObjectInputStream(in);

                    System.out.println("客户端连接服务器成功！！！");
                }
            }while(startMenu(objOut,objIn)!=0);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(objIn!=null)
                    objIn.close();
                if(objOut!=null)
                    objOut.close();
                if(client!=null)
                    client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 起始菜单
     * @return
     */
    public int startMenu(ObjectOutputStream objOut,ObjectInputStream objIn){
        int num=0;
        do {
            System.out.println("------欢迎来到开课吧快递管理系统--------");
            System.out.println("请选择：");
            System.out.println("1、管理员");
            System.out.println("2、普通用户");
            System.out.println("0、退出");
            String strNum = input.nextLine();
            try {
                num = validateNum(strNum, 0, 2);
                break;
            } catch (NumberFormatException e) {
                System.err.println(e.getMessage());
                //e.printStackTrace();
            } catch (OutNumberBoundException e) {
                System.err.println(e.getMessage());
                //e.printStackTrace();
            }
        }while(true);
        try {
            if(num==1){
                administorMenu(objOut,objIn);
            }else if(num==2){
               userMenu(objOut,objIn);
            }else if(num==0){
                System.out.println("谢谢使用！");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(objIn!=null)
                    objIn.close();
                if(objOut!=null)
                    objOut.close();
                if(client!=null)
                    client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return num;
    }

    /**
     * 用户菜单
     */
    public void userMenu(ObjectOutputStream objOut,ObjectInputStream objIn) throws IOException, ClassNotFoundException {
        int code;
        do {
            System.out.print("请输入取件码:");
            String strCode = input.nextLine();
            try {
                code = validateNum(strCode, 100000, 900000);
                break;
            } catch (OutNumberBoundException e) {
               // e.printStackTrace();
                System.err.println(e.getMessage());
            }
        }while(true);
        //客户端无法直接调用服务器端的dao,所以只能向服务器发送请求，然后等待响应
        //发送请求到服务器--写数据
        objOut.writeUTF("findByCode");
        objOut.writeObject(code);
        objOut.flush();
        //接受服务器端的响应结果--读数据
        Object obj=objIn.readObject();
        if(obj instanceof  Express) {
            Express express = (Express) obj;//expressDao.findExpressByCode(code);

                System.out.println("从柜子中取出成功！快递信息：" + express);


        }else if(obj instanceof  String ){
            System.out.println("取出失败！"+(String)obj);
        }else{
            System.out.println("取出失败！"+obj);
        }
    }

    /**
     * 管理员菜单
     */
    private void administorMenu(ObjectOutputStream objOut,ObjectInputStream objIn) throws IOException, ClassNotFoundException {
        int num;
        do {
            System.out.println("1、快递录入");
            System.out.println("2、快递删除");
            System.out.println("3、快递修改");
            System.out.println("4、查看所有快递");
            System.out.println("0、返回上一级菜单");
            System.out.print("请选择功能序号：");
            String strNum = input.nextLine();
            try {
                num = validateNum(strNum, 0, 4);
                break;
            } catch (NumberFormatException e) {
                System.err.println(e.getMessage());
                //e.printStackTrace();
            } catch (OutNumberBoundException e) {
                System.err.println(e.getMessage());
                //e.printStackTrace();
            }
        }   while(true);

        if(num==1){
           addExpress(objOut,objIn);
        }else if(num==2){
          deleteExpress(objOut,objIn);
        }else if(num==3){
           updateExpress(objOut,objIn);
        }else if(num==4){
           findAll(objOut,objIn);
        }else if(num==0){
            startMenu(objOut,objIn);
        }
    }

    /**
     * 查询所有
     */
    public void findAll(ObjectOutputStream objOut,ObjectInputStream objIn) throws IOException, ClassNotFoundException {
        System.out.println("-------查看所有快递-------");
        //客户端无法直接调用服务器端的dao,所以只能向服务器发送请求，然后等待响应
        //发送请求到服务器--写数据
        objOut.writeUTF("findAll");
        objOut.flush();
        //接受服务器端的响应结果--读数据
        Object obj=objIn.readObject();
        if(obj instanceof List) {
            List<Express> expressList = (List<Express>) obj;//expressDao.getExpressList();
            for (Express express : expressList) {
                System.out.println(express);
            }
        }else if(obj instanceof  String){
            System.out.println((String)obj);
        }else{
            System.out.println(obj);
        }
    }
    /**
     * 修改快递
     */
    public  void updateExpress(ObjectOutputStream objOut,ObjectInputStream objIn){
        System.out.println("----------快递修改------------");
        System.out.print("请输入要修改的快递单号：");
        String number=input.nextLine();
        Express newExpress=new Express();
        System.out.println("请输入修改后的快递单号和公司：");
        newExpress.setNumber(input.nextLine());
        newExpress.setCompany(input.nextLine());
        try {
            //客户端无法直接调用服务器端的dao,所以只能向服务器发送请求，然后等待响应
            //发送请求到服务器--写数据
            objOut.writeUTF("update");
            objOut.writeObject(number);
            objOut.writeObject(newExpress);
            objOut.flush();
            //接受服务器端的响应结果--读数据
            Object obj=objIn.readObject();
            if(obj instanceof Boolean){
                boolean res= (boolean) obj;
                if(res){
                    System.out.println("修改成功！");
                }else{
                    System.out.println("修改失败！");
                }
            }else if(obj instanceof  String){
                System.out.println("修改失败！"+(String)obj);
            }else{
                System.out.println("修改失败！"+obj);
            }

        } catch (Exception exception) {
            System.out.println("修改失败！");
            System.out.println(exception.getMessage());
        }
    }
    /**
     * 删除快递
     */
    private void deleteExpress(ObjectOutputStream objOut,ObjectInputStream objIn){
        System.out.println("------快递删除-");
        System.out.print("请输入要删除的快递单号：");
        String number=input.nextLine();
        try {
            //客户端无法直接调用服务器端的dao,所以只能向服务器发送请求，然后等待响应
            //发送请求到服务器--写数据
            objOut.writeUTF("delete");
            objOut.writeObject(number);
            objOut.flush();
            //接受服务器端的响应结果--读数据
            Object obj=objIn.readObject();
            if(obj instanceof  Boolean) {
                boolean res= (boolean) obj;
                if (res) {
                    System.out.println("删除成功！");
                } else {
                    System.out.println("删除失败！");
                }
            }else if(obj instanceof  String){
                System.out.println("删除失败！"+(String)obj);
            }else{
                System.out.println("删除失败！"+obj);
            }
        } catch (Exception exception) {
            System.out.println("删除失败！");
            System.err.println(exception.getMessage());
        }
    }

    /**
     * 快递录入
     */
    private void addExpress(ObjectOutputStream objOut,ObjectInputStream objIn){
        System.out.println("-------快递录入----------");
        Express express=new Express();
        System.out.println("请输入快递单号和公司");
        express.setNumber(input.nextLine());
        express.setCompany(input.nextLine());
        try {
            //客户端无法直接调用服务器端的dao,所以只能向服务器发送请求，然后等待响应
            //发送请求到服务器--写数据
            objOut.writeUTF("add");
            objOut.writeObject(express);
            objOut.flush();
            //接受服务器端的响应结果--读数据
            Object obj=objIn.readObject();//expressDao.add(express);
            if(obj instanceof  Express) {
                express= (Express) obj;
                System.out.println("添加成功！放在快递柜中第" + (express.getX() + 1) + "排第" + (express.getY() + 1) + "列");
            }else if(obj instanceof  String){
                System.out.println("添加失败！"+(String)obj);
            }else{
                System.out.println("添加失败！"+obj);
            }
        } catch (Exception exception) {
            System.out.println("添加失败！");
            System.err.println(exception.getMessage());
            exception.printStackTrace();
        }
    }

    /**
     * 验证用户输入是否合法
     * @param strNum
     * @param begin
     * @param end
     * @return
     * @throws NumberFormatException
     * @throws OutNumberBoundException
     */
    private int validateNum(String strNum,int begin,int end) throws NumberFormatException,OutNumberBoundException{
        try {
            int num=Integer.valueOf(strNum);
            if(num<begin || num>end){
                throw new OutNumberBoundException("数字的范围必须在"+begin+"和"+end+"之间！");
            }
            return num;
        }catch (NumberFormatException exception){
            throw new NumberFormatException("输入的必须是数字！");
        }
    }

}
